package com.letoken.platform.app.job;


import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.letoken.platform.app.service.AppUserIssueHistoryService;
import com.letoken.platform.app.service.AppUserIssueService;
import com.letoken.platform.app.service.AppUserLogService;
import com.letoken.platform.pub.constant.ConstantsValue;
import com.letoken.platform.pub.enums.BalanceTypeEnum;
import com.letoken.platform.pub.enums.InOutTypeEnum;
import com.letoken.platform.pub.enums.LetokenTokenTypeEnum;
import com.letoken.platform.pub.util.LocalDateTool;
import com.letoken.platform.pub.util.RedisIdeTool;
import com.letoken.platform.repo.admin.dao.AdminIssueConfigMapper;
import com.letoken.platform.repo.admin.util.CollectionUtils;
import com.letoken.platform.repo.app.dao.*;
import com.letoken.platform.repo.app.po.AppUserIssue;
import com.letoken.platform.repo.app.po.AppUserIssueHistory;
import com.letoken.platform.repo.app.po.AppUserWallet;
import com.letoken.platform.repo.app.res.config.QueryAppIssueConfigRes;
import com.letoken.platform.repo.mall.po.AppBalanceHistory;
import com.letoken.platform.repo.mall.po.AppBalanceWallet;
import com.letoken.platform.repo.utlis.UniqueIDUtils;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;


@Component
@Slf4j
public class CalculateBalanceIncomeJob {


    @Autowired
    AppBalanceWalletMapper appBalanceWalletMapper;
    @Autowired
    AppBalanceHistoryMapper appBalanceHistoryMapper;
    @Autowired
    RedisIdeTool redisIdeTool;



    @XxlJob("calculateBalanceIncome")
    public  void calculateBalanceIncome() {
        try {
            if (!redisIdeTool.checkAndSetStr(RedisIdeTool.TASK_RUNNING,"BALANCE_CAL")){
                log.info("当前有计算余额收益任务在执行，放弃本次执行");
                return;
            }

            LocalDateTime now = LocalDateTime.now();
            LocalDateTime excludeTime = LocalDateTool.plusDayFull(now,-1);
            List<AppBalanceWallet> list = appBalanceWalletMapper.allBalanceUser();
            if (CollectionUtils.isNotEmpty(list)){
                list.parallelStream().forEach(x->{
                    try{
                        if (null != appBalanceHistoryMapper.isExitsCalculate(x.getUserId(),BalanceTypeEnum.INCOME.ordinal())){
                            log.info("该用户今日已经计算过收益 {}",x.getUserId());
                            return;
                        }
                        SpringUtil.getBean(CalculateBalanceIncomeJob.class).changeBalance(x.getId(),now,excludeTime);
                    }catch (Exception e){
                        log.error("计算收益失败! 用户ID：{}",x.getUserId(),e);
                    }
                });
            }
        } catch (Exception e) {
            log.error("计算余额收益失败!",e);
        }finally {
            redisIdeTool.delStr(RedisIdeTool.TASK_RUNNING,"BALANCE_CAL");
        }
    }


    @Transactional
    public void changeBalance(Integer id,LocalDateTime now,LocalDateTime excludeTime){
        AppBalanceWallet b = appBalanceWalletMapper.selectForUpdate(id);
        BigDecimal balance = b.getBalance();
        BigDecimal e = appBalanceWalletMapper.excludeDissatisfaction(b.getUserId(),excludeTime);
        if (ObjectUtils.isNotEmpty(e) && e.compareTo(BigDecimal.ZERO) > 0){
            balance = balance.subtract(e);
        }
        if (balance.compareTo(BigDecimal.ZERO) <= 0){
            return;
        }

        BigDecimal dayIncome  = balance.multiply(ConstantsValue.BALANCE_INCOME_RATE.divide(BigDecimal.valueOf(30),10,RoundingMode.DOWN)).setScale(8,RoundingMode.DOWN);
        if (dayIncome.compareTo(BigDecimal.ZERO) > 0){
            AppBalanceWallet updateB = new AppBalanceWallet();
            updateB.setId(id);
            updateB.setBalance(b.getBalance().add(dayIncome));
            updateB.setIncome(b.getIncome().add(dayIncome));
            updateB.setUpdateTime(now);
            appBalanceWalletMapper.updateById(updateB);

            AppBalanceHistory abh = new AppBalanceHistory();
            abh.setBalance(updateB.getBalance());
            abh.setAmount(dayIncome);
            abh.setType(BalanceTypeEnum.INCOME.ordinal());
            abh.setInOut(InOutTypeEnum.IN.ordinal());
            abh.setSeqNo(UniqueIDUtils.genSeqNo("IC"));
            abh.setTokenId(LetokenTokenTypeEnum.LET.getId());
            abh.setUserId(b.getUserId());
            abh.setCreateTime(now);
            appBalanceHistoryMapper.insert(abh);
        }
    }


}
